package com.mjlf.boot;

import com.mjlf.boot.service.ClientServer;
import com.mjlf.boot.service.ScreenControlClient;
import com.mjlf.boot.service.ScreenControlService;
import org.apache.thrift.transport.TTransportException;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;

/**
 * @ClassName Client
 * @Author mjlft
 * @Date 2020/3/6 14:38
 * @Version 1.0
 * @Description 界面客户端
 * 本程序第一个版本通过thrift发送简单的鼠标键盘控制事件到服务端，进而实现远程屏幕控制的方式
 * 在市面上大多都是通过屏幕截图，然后实现再实现远程控制，而我这里希望将这个程序用在局域网，一个伙伴有两台电脑
 * 而不想反复的移动位置就完成两台电脑的操作
 *
 * 远程过程调用使用thrift实现输出传输
 *
 * 使用Robot实现鼠标键盘事件的模拟
 *
 * 通过鼠标移除屏幕实现切屏功能
 *
 * 需要注意的是， 1.0.0版本只能实现两台电脑向后控制，而且没有实现断链重试， 也不支持文件传输，也不支持终端控制
 * 再后续的迭代中陆续实现，而且现在这个版本效率还相对较低
 *
 * 加油吧
 *
 * 原理：
 * 服务端很简单，就是启动一个thrift服务，然后等待客户端发送指定过来，让后使用robot模拟事件，就这么简单
 * 客户端相对麻烦些：
 *  1.客户端首先需要判断当前操作的是自己还是服务端屏幕
 *      判断依旧是当前鼠标的指针位置，如果鼠标指针位置移动到屏幕右边边界外，那么就进入到控制服务端屏幕
 *      于此同时如果鼠标指针移动屏幕左边边界外，那么回到客户端屏幕
 *  2. 客户端怎么实现捕获鼠标键盘事件
 *      在控制自己的时候，程序界面放到右上角，界面最小化，这样该做什么做什么
 *      再控制服务端屏幕的时候，这是最麻烦的
 *      怎么控制捕获鼠标键盘事件，同时自己的电脑没有想要，而且还不影响自己屏幕的显示，总不能显示一个大的空白屏幕吧
 *      其实就是显示一个大空白屏幕，只是将这个屏幕设置为透明的，其实半透明的，这样不会影响自己的显示，还能捕获到鼠标键盘事件
 *      但是需要注意的是，完全透明是没有办法捕获到界面上的事件的，这样操作的还是自己的屏幕
 * 3.怎么实现再控制服务端屏幕的时候自己的鼠标不动
 *      这个其实是做不到的，我们也是通过自己鼠标的为而实现相对再远程控制鼠标移动的，如果自己的鼠标不让动，那就没有办法实现服务端
 *      鼠标移动
 *      其实这个问题很简单，再控制服务端屏幕的时候，将自己的鼠标设置为透明的就可以了，这样就实现了像是完全在控制服务端屏幕
 *      包括鼠标都是由自己的屏幕移动过去
 */
public class Client extends JFrame {

    private static final JPanel contentPanel = new JPanel();

    public Client() throws HeadlessException {
        setTitle("控屏");
        setSize(260, 200);
        setLocationRelativeTo(null);
//        setUndecorated(true);
//        setBackground(new Color(0,0,0,0));
//        setOpacity(0.5f);
        getContentPane().setLayout(new BorderLayout());

        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(null);
        contentPanel.setOpaque(false);

        //添加程序标题，中控制面板上显示的文字
        JLabel lblx = new JLabel("屏控");
        lblx.setFont(new Font("宋体", Font.BOLD, 30));
        lblx.setBounds(97, 30, 66, 31);
        contentPanel.add(lblx);

        //添加服务端和客户端两个功能选择按钮
        JButton server = new JButton();
        server.setText("服务端");
        server.setBorder(new BevelBorder(0));
        server.setBounds(20, 90, 90, 60);
        //服务端功能按钮鼠标监听事件
        server.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                try {
                    //打开服务端监控程序
                    ScreenControlService.start();
                    //处理中控屏，将画面最小化，并移动到右上角
                    startCallBack();
                } catch (TTransportException ex) {
                    ex.printStackTrace();
                }
            }

            public void mousePressed(MouseEvent e) {

            }

            public void mouseReleased(MouseEvent e) {

            }

            public void mouseEntered(MouseEvent e) {

            }

            public void mouseExited(MouseEvent e) {

            }
        });
        contentPanel.add(server);

        //添加客户端功能选择按钮
        JButton client = new JButton();
        client.setText("客户端");
        client.setBorder(new BevelBorder(0));
        client.setBounds(150, 90, 90, 60);
        //客户端功能选择按钮鼠标事件监听
        client.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //移除控制面板上的两个功能选择按钮
                contentPanel.remove(client);
                contentPanel.remove(server);

                //添加主机标题文字
                JLabel lblx = new JLabel("主机:");
                lblx.setFont(new Font("宋体", Font.PLAIN, 15));
                lblx.setBounds(5, 90, 50, 30);
                contentPanel.add(lblx);

                //添加主机文本输入框
                JTextField host = new JTextField(50);
                host.setBounds(50, 90, 180, 30);
                host.setText("localhost");
                host.setVisible(true);
                contentPanel.add(host);
                contentPanel.setVisible(true);
                host.addKeyListener(new KeyListener() {
                    @Override
                    public void keyTyped(KeyEvent e) {

                    }

                    @Override
                    public void keyPressed(KeyEvent e) {

                    }

                    @Override
                    public void keyReleased(KeyEvent e) {
                        if (e.getKeyCode() == 10) {
                            connect(host);
                        }
                    }
                });

                //添加连接服务端按钮
                JButton server = new JButton();
                server.setText("连接");
                server.setBorder(new BevelBorder(0));
                server.setBounds(180, 125, 50, 30);
                server.addMouseListener(new MouseListener() {
                    public void mouseClicked(MouseEvent e) {
                        connect(host);
                    }

                    public void mousePressed(MouseEvent e) {

                    }

                    public void mouseReleased(MouseEvent e) {

                    }

                    public void mouseEntered(MouseEvent e) {

                    }

                    public void mouseExited(MouseEvent e) {

                    }
                });
                contentPanel.add(server);

                contentPanel.validate();
                contentPanel.repaint();
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });
        contentPanel.add(client);
    }

    public void connect(JTextField host) {
        String remoteHost = host.getText();
        try {
            ScreenControlClient.connect(remoteHost);
        } catch (Exception ex) {
            host.setText("error : " + ex.getMessage());
        }
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((int) (dimension.getWidth() - 260), 0, 260, 0);
        removeAll();
        validate();
        repaint();

        clientCallBack();
    }

    public void startCallBack() {
        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        this.setBounds((int) (dimension.getWidth() - 260), 0, 260, 0);

        //移除中控面板上的所有组件
        removeAll();
        validate();
        //重画
        repaint();
    }

    public void clientCallBack() {

        //打开客户端，实现屏幕事件监控
        new Thread(new ClientServer(this)).start();
    }

    public static void main(String[] args) {
        Client client = new Client();
        client.setVisible(true);
        client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
